package com.reservation.service;

import com.reservation.dto.ProductDTO;
import com.reservation.dto.ProductRequest;
import com.reservation.entity.Product;
import com.reservation.mapper.ProductMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 商品服务类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ProductService {

    private final ProductMapper productMapper;

    /**
     * 获取所有商品
     */
    public List<ProductDTO> getAllProducts() {
        log.info("获取所有商品列表");
        List<Product> products = productMapper.selectAllActive();
        return products.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 获取有库存的商品
     */
    public List<ProductDTO> getAvailableProducts() {
        log.info("获取有库存的商品列表");
        List<Product> products = productMapper.selectAvailable();
        return products.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 根据ID获取商品
     */
    public Optional<ProductDTO> getProductById(Long id) {
        log.info("根据ID获取商品: {}", id);
        Product product = productMapper.selectByIdAndActive(id);
        return Optional.ofNullable(product).map(this::convertToDTO);
    }

    /**
     * 根据名称搜索商品
     */
    public List<ProductDTO> searchProductsByName(String name) {
        log.info("根据名称搜索商品: {}", name);
        List<Product> products = productMapper.selectByNameLike(name);
        return products.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 减少商品库存
     */
    @Transactional
    public void decreaseStock(Long productId, Integer quantity) {
        log.info("减少商品库存: productId={}, quantity={}", productId, quantity);
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        if (!product.hasEnoughStock(quantity)) {
            throw new RuntimeException("库存不足");
        }

        product.decreaseStock(quantity);
        productMapper.update(product);
        log.info("商品库存减少成功: productId={}, 剩余库存={}", productId, product.getStock());
    }

    /**
     * 增加商品库存
     */
    @Transactional
    public void increaseStock(Long productId, Integer quantity) {
        log.info("增加商品库存: productId={}, quantity={}", productId, quantity);
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        product.increaseStock(quantity);
        productMapper.update(product);
        log.info("商品库存增加成功: productId={}, 当前库存={}", productId, product.getStock());
    }

    /**
     * 检查库存是否充足
     */
    public boolean checkStock(Long productId, Integer quantity) {
        Product product = productMapper.selectById(productId);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }
        return product.hasEnoughStock(quantity);
    }

    /**
     * 获取库存不足的商品
     */
    public List<ProductDTO> getLowStockProducts(Integer threshold) {
        log.info("获取库存不足的商品: threshold={}", threshold);
        List<Product> products = productMapper.selectLowStock(threshold);
        return products.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 新增商品
     */
    @Transactional
    public ProductDTO createProduct(ProductRequest request) {
        log.info("新增商品: name={}", request.getName());

        Product product = convertToEntity(request);
        int result = productMapper.insert(product);

        if (result <= 0) {
            throw new RuntimeException("新增商品失败");
        }

        log.info("商品新增成功: id={}, name={}", product.getId(), product.getName());
        return convertToDTO(product);
    }

    /**
     * 编辑商品
     */
    @Transactional
    public ProductDTO updateProduct(Long id, ProductRequest request) {
        log.info("编辑商品: id={}, name={}", id, request.getName());

        Product existingProduct = productMapper.selectById(id);
        if (existingProduct == null) {
            throw new RuntimeException("商品不存在");
        }

        Product product = convertToEntity(request);
        product.setId(id);
        product.setCreatedAt(existingProduct.getCreatedAt());

        int result = productMapper.update(product);
        if (result <= 0) {
            throw new RuntimeException("编辑商品失败");
        }

        log.info("商品编辑成功: id={}, name={}", id, product.getName());
        return convertToDTO(productMapper.selectById(id));
    }

    /**
     * 删除商品
     */
    @Transactional
    public void deleteProduct(Long id) {
        log.info("删除商品: id={}", id);

        Product product = productMapper.selectById(id);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }

        int result = productMapper.deleteById(id);
        if (result <= 0) {
            throw new RuntimeException("删除商品失败");
        }

        log.info("商品删除成功: id={}", id);
    }

    /**
     * 批量删除商品
     */
    @Transactional
    public void deleteProducts(List<Long> ids) {
        log.info("批量删除商品: ids={}", ids);

        if (ids == null || ids.isEmpty()) {
            throw new RuntimeException("删除商品ID列表不能为空");
        }

        int result = productMapper.deleteByIds(ids);
        if (result <= 0) {
            throw new RuntimeException("批量删除商品失败");
        }

        log.info("批量删除商品成功: 删除数量={}", result);
    }

    /**
     * 转换请求对象为实体
     */
    private Product convertToEntity(ProductRequest request) {
        Product product = new Product();
        product.setName(request.getName());
        product.setPrice(request.getPrice());
        product.setImage(request.getImage());
        product.setStock(request.getStock());
        product.setDescription(request.getDescription());
        product.setIsActive(request.getIsActive());
        return product;
    }

    /**
     * 转换为DTO
     */
    private ProductDTO convertToDTO(Product product) {
        ProductDTO dto = new ProductDTO();
        dto.setId(product.getId());
        dto.setName(product.getName());
        dto.setPrice(product.getPrice());
        dto.setImage(product.getImage());
        dto.setStock(product.getStock());
        dto.setDescription(product.getDescription());
        dto.setIsActive(product.getIsActive());
        dto.setCreatedAt(product.getCreatedAt());
        dto.setUpdatedAt(product.getUpdatedAt());
        return dto;
    }
}
